#include"bmp.h"

int main(int argc, char const *argv[])
{
    //1.打开lcd
    int lcd = open("/dev/fb0", O_RDWR);//路径错误，fb0是一个文件，不是目录
    struct fb_var_screeninfo vinfo;
    ioctl(lcd, FBIOGET_VSCREENINFO, &vinfo);
    int lcd_w = vinfo.xres;
    int lcd_h = vinfo.yres;
    int bpp   = vinfo.bits_per_pixel;
    int screen_size = lcd_w * lcd_h * bpp/8;
    char *fb_mem = mmap(NULL, screen_size, PROT_WRITE, MAP_SHARED, lcd, 0);

    //2.打开bmp并读取格式头
    FILE *fp = fopen(argv[1], "rb");
    struct bitmap_header head;
    struct bitmap_info   info;
    fread(&head, sizeof(head), 1, fp);
    fread(&info, sizeof(info), 1, fp);
    if(info.compression){
        struct rgb_quad quad;
        fread(&quad, sizeof(quad), 1, fp);
    }
    printf("图片规格:%d × %d [%d]\n", info.width, info.height, head.size);
    
    //3.读bmp数据
    int rgb_size = head.size - sizeof(head) - sizeof(info);//错误点1：错误计算大小
    char *rgb_data = malloc(rgb_size);
    fread(rgb_data, rgb_size, 1, fp);

    //4.正确显示图片
    //4.1计算bmp_pad
    int rgb_pad = (4 - (info.width * info.bit_count/8) %4) %4;
    //4.2计算lcd一行偏移量
    int lcd_line = lcd_w * bpp/8;
    //4.3计算bmp一行偏移量
    int rgb_line = info.width * info.bit_count/8 + rgb_pad;
    //显示图片
    for(int i = 0; i < lcd_h && i < info.height; i++){
        int lcd_offset = lcd_line * i;
        int rgb_offset = rgb_line * (info.height - 1 - i);
        for(int j = 0; j < lcd_w && j < info.width; j++)
            memcpy(fb_mem + j*bpp/8 + lcd_offset, 
                rgb_data + j*info.bit_count/8 + rgb_offset, 
                info.bit_count/8);
    }
    //释放相关资源
    free(rgb_data);
    munmap(fb_mem, screen_size);
    fclose(fp);
    close(lcd);
    return 0;
}
